package com.example.library.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.library.common.ResultCode;
import com.example.library.dto.LoginRequest;
import com.example.library.dto.RegisterRequest;
import com.example.library.dto.UserQueryRequest;
import com.example.library.entity.User;
import com.example.library.mapper.UserMapper;
import com.example.library.service.UserService;
import com.example.library.utils.JwtUtils;
import com.example.library.utils.PasswordUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户服务实现类
 *
   */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserMapper userMapper;
    private final JwtUtils jwtUtils;

    @Override
    public String login(LoginRequest loginRequest) {
        // 查询用户
        User user = findByUsername(loginRequest.getUsername());
        if (user == null) {
            throw new RuntimeException(ResultCode.USER_NOT_FOUND.getMessage());
        }

        // 检查用户状态
        if (!user.isEnabled()) {
            throw new RuntimeException(ResultCode.USER_DISABLED.getMessage());
        }

        // 验证密码
        if (!PasswordUtils.matches(loginRequest.getPassword(), user.getPassword())) {
            throw new RuntimeException(ResultCode.USERNAME_OR_PASSWORD_ERROR.getMessage());
        }

        // 生成JWT令牌
        return jwtUtils.generateToken(user.getId(), user.getUsername(), user.getRole());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public User register(RegisterRequest registerRequest) {
        // 检查密码确认
        if (!registerRequest.getPassword().equals(registerRequest.getConfirmPassword())) {
            throw new RuntimeException(ResultCode.PASSWORD_NOT_MATCH.getMessage());
        }

        // 检查用户名是否存在
        if (existsByUsername(registerRequest.getUsername())) {
            throw new RuntimeException(ResultCode.USER_ALREADY_EXISTS.getMessage());
        }

        // 检查邮箱是否存在
        if (existsByEmail(registerRequest.getEmail())) {
            throw new RuntimeException("邮箱已被注册");
        }

        // 检查手机号是否存在
        if (StringUtils.isNotBlank(registerRequest.getPhone()) && existsByPhone(registerRequest.getPhone())) {
            throw new RuntimeException("手机号已被注册");
        }

        // 创建用户
        User user = new User();
        LocalDateTime now = LocalDateTime.now();
        user.setUsername(registerRequest.getUsername());
        user.setPassword(PasswordUtils.encode(registerRequest.getPassword()));
        user.setEmail(registerRequest.getEmail());
        user.setPhone(registerRequest.getPhone());
        user.setRole(User.ROLE_USER);
        user.setStatus(User.STATUS_ENABLED);
        user.setCreatedTime(now);
        user.setUpdatedTime(now);

        if (!save(user)) {
            throw new RuntimeException("用户注册失败");
        }

        return user;
    }

    @Override
    public User findByUsername(String username) {
        return userMapper.findByUsername(username);
    }

    @Override
    public User findByEmail(String email) {
        return userMapper.findByEmail(email);
    }

    @Override
    public IPage<User> getUserPage(UserQueryRequest queryRequest) {
        Page<User> page = new Page<>(queryRequest.getCurrent(), queryRequest.getSize());
        return userMapper.selectUserPage(page,
                queryRequest.getUsername(),
                queryRequest.getRealName(),
                queryRequest.getRole(),
                queryRequest.getStatus());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createUser(User user) {
        // 检查用户名是否存在
        if (existsByUsername(user.getUsername())) {
            throw new RuntimeException(ResultCode.USER_ALREADY_EXISTS.getMessage());
        }

        // 检查邮箱是否存在
        if (StringUtils.isNotBlank(user.getEmail()) && existsByEmail(user.getEmail())) {
            throw new RuntimeException("邮箱已被使用");
        }

        // 加密密码
        if (StringUtils.isNotBlank(user.getPassword())) {
            user.setPassword(PasswordUtils.encode(user.getPassword()));
        } else {
            // 设置默认密码
            user.setPassword(PasswordUtils.encode("123456"));
        }

        // 设置默认值
        if (user.getRole() == null) {
            user.setRole(User.ROLE_USER);
        }
        if (user.getStatus() == null) {
            user.setStatus(User.STATUS_ENABLED);
        }

        return save(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUser(User user) {
        User existingUser = getById(user.getId());
        if (existingUser == null) {
            throw new RuntimeException(ResultCode.USER_NOT_FOUND.getMessage());
        }

        // 检查用户名是否被其他用户使用
        if (!existingUser.getUsername().equals(user.getUsername()) && existsByUsername(user.getUsername())) {
            throw new RuntimeException("用户名已被使用");
        }

        // 检查邮箱是否被其他用户使用
        if (StringUtils.isNotBlank(user.getEmail()) &&
                !user.getEmail().equals(existingUser.getEmail()) &&
                existsByEmail(user.getEmail())) {
            throw new RuntimeException("邮箱已被使用");
        }

        // 不更新密码字段
        user.setPassword(null);
        user.setUpdatedTime(LocalDateTime.now());
        return updateById(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(Long userId) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException(ResultCode.USER_NOT_FOUND.getMessage());
        }

        // 不能删除管理员
        if (user.isAdmin()) {
            throw new RuntimeException("不能删除管理员用户");
        }

        return removeById(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteUsers(List<Long> userIds) {
        // 检查是否包含管理员
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(User::getId, userIds).eq(User::getRole, User.ROLE_ADMIN);
        long adminCount = count(wrapper);
        if (adminCount > 0) {
            throw new RuntimeException("不能删除管理员用户");
        }

        return removeByIds(userIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserStatus(Long userId) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException(ResultCode.USER_NOT_FOUND.getMessage());
        }

        if (user.isEnabled()){
            user.setStatus(User.STATUS_DISABLED);
        }else {
            user.setStatus(User.STATUS_ENABLED);
        }
        return updateById(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateUserStatus(List<Long> userIds, Integer status) {
        return userMapper.batchUpdateStatus(userIds, status) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resetPassword(Long userId, String newPassword) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException(ResultCode.USER_NOT_FOUND.getMessage());
        }

        user.setPassword(PasswordUtils.encode(newPassword));
        return updateById(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean changePassword(Long userId, String oldPassword, String newPassword) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException(ResultCode.USER_NOT_FOUND.getMessage());
        }

        // 验证旧密码
        if (!PasswordUtils.matches(oldPassword, user.getPassword())) {
            throw new RuntimeException(ResultCode.OLD_PASSWORD_ERROR.getMessage());
        }

        user.setPassword(PasswordUtils.encode(newPassword));
        return updateById(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAvatar(Long userId, String avatar) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException(ResultCode.USER_NOT_FOUND.getMessage());
        }

        user.setAvatar(avatar);
        return updateById(user);
    }

    @Override
    public Object getUserStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 总用户数
        statistics.put("totalUsers", count());
        
        // 管理员数量
        statistics.put("adminCount", userMapper.countUsers(User.ROLE_ADMIN, null));
        
        // 普通用户数量
        statistics.put("userCount", userMapper.countUsers(User.ROLE_USER, null));
        
        // 启用用户数量
        statistics.put("enabledUsers", userMapper.countUsers(null, User.STATUS_ENABLED));
        
        // 禁用用户数量
        statistics.put("disabledUsers", userMapper.countUsers(null, User.STATUS_DISABLED));
        
        return statistics;
    }

    @Override
    public boolean existsByUsername(String username) {
        return findByUsername(username) != null;
    }

    @Override
    public boolean existsByEmail(String email) {
        return findByEmail(email) != null;
    }

    @Override
    public boolean existsByPhone(String phone) {
        return userMapper.findByPhone(phone) != null;
    }

}